package edu.gatech.oad.publicstaticdroidmain.taskmanager.ui;

import android.app.Activity;
import android.test.ActivityInstrumentationTestCase2;
import edu.gatech.oad.publicstaticdroidmain.taskmanager.model.InputValidator;
import edu.gatech.oad.publicstaticdroidmain.taskmanager.model.LocationHelper;
import edu.gatech.oad.publicstaticdroidmain.taskmanager.model.Task;
import edu.gatech.oad.publicstaticdroidmain.taskmanager.persistence.DataSourceInterface;
import edu.gatech.oad.publicstaticdroidmain.taskmanager.persistence.TaskManagerSQLiteDatabase;

public class TestLoginActivity extends ActivityInstrumentationTestCase2<LoginActivity> {

	DataSourceInterface db;
	
	public TestLoginActivity(Class<LoginActivity> activityClass) {
		super(activityClass);
		// TODO Auto-generated constructor stub
	}

	public TestLoginActivity(String pkg, Class<TestLoginActivity> activityClass) {
		super("edu.gatech.oad.publicstaticdroudmain.taskmanager.ui", LoginActivity.class);
		// TODO Auto-generated constructor stub
	}
	
	public TestLoginActivity() {
		super("edu.gatech.oad.publicstaticdroudmain.taskmanager.ui", LoginActivity.class);
	}

	@Override
	public void setUp() throws Exception {
		super.setUp();
		Activity mActivity = this.getActivity();
		db = new TaskManagerSQLiteDatabase(mActivity);
	}

	public void testUpdateRealName(){
		db.open();
		db.clear();
		db.createUser("username", "password", "Tyler", "email");
		assertTrue(db.updateRealName("username", "testName"));
		assertTrue(db.getRealName("username").equals("testName"));
		//assertFalse(db.updateUsername("i'm not real!", "name"));
		assertFalse(db.updateUsername("im not real!", "name"));
		try {
			db.updateRealName("username", null);
			fail();
		} catch(IllegalArgumentException IAE) {
		
		}
		try {
			db.updateRealName(null,"name");
			fail();
		} catch(IllegalArgumentException IAE) {
		}
		
		db.close();		
	}
	public void testUpdateEmailAddress(){
		db.open();
		db.clear();
		db.createUser("username", "password", "Tyler", "email");
		assertTrue(db.updateEmailAddress("username", "testEmail"));
		assertFalse(db.updateUsername("im not real!", "name"));
		try {
			db.updateEmailAddress("username", null);
			fail();
		} catch(IllegalArgumentException IAE) {
		
		}
		try {
			db.updateEmailAddress(null,"testEmail");
			fail();
		} catch(IllegalArgumentException IAE) {
		}
		
		db.close();		
	}
	
	
	public void testCreateUser() {
		db.open();
		db.clear();
		assertTrue(db.createUser("username", "password", "name", "email"));
		assertTrue(db.userExists("username"));
		assertTrue(db.verifyCredentials("username", "password"));
		assertTrue(db.createUser("", "", "", ""));
		assertTrue(db.userExists(""));
		assertTrue(db.verifyCredentials("", ""));
		try {
			db.createUser("username", "password", "name", null);
			fail();
		} catch(IllegalArgumentException IAE) {
			
		}
		db.close();
	}
	
	public void testUserExists() throws Exception {
		db.open();
		db.clear();
		assertFalse(db.userExists("username"));
		db.createUser("username","password","name","email");
		assertFalse(db.userExists("not username"));
		assertFalse(db.userExists(""));
		assertTrue(db.userExists("username"));
		try {
			db.userExists(null);
			fail();
		} catch(IllegalArgumentException IAE) {
			
		}
		db.close();
	}
	
	public void testVerifyCredentials() throws Exception {
		db.open();
		db.clear();
		db.createUser("username", "password", "name", "email");
		assertTrue(db.verifyCredentials("username", "password"));
		assertFalse(db.verifyCredentials("username", "not password"));
		assertFalse(db.verifyCredentials("not username", "password"));
		try {
			db.verifyCredentials("username", null);
			fail();
		} catch(IllegalArgumentException IAE) {
			
		}
		db.close();
	}
	
	public void testUpdateUsername() throws Exception {
		db.open();
		db.clear();
		db.createUser("username", "password", "name", "email");
		assertTrue(db.updateUsername("username", "newUsername"));
		assertTrue(db.updateUsername("newUsername", "anotherUsername"));
		assertFalse(db.updateUsername("username", "blah"));
		assertFalse(db.updateUsername("IDoNotExist", "blah"));
		try {
			db.updateUsername("username", null);
			fail();
		} catch(IllegalArgumentException IAE) {
			
		}
		db.close();
	}
	
	public void testAddCategory() {
	    db.open();
	    db.clear();
	    
	    String username = "username";
	    db.createUser(username, "password", "name", "email");
	    
	    assertTrue(db.categoryExists(username, "Personal"));
	    assertFalse(db.addCategory(username, "Personal"));
	    assertTrue(db.categoryExists(username, "Work"));
	    assertFalse(db.addCategory(username, "Work"));
	    assertTrue(db.categoryExists(username, "School"));
	    assertFalse(db.addCategory(username, "School"));
	    
	    assertTrue(db.addCategory(username, "new 1"));
	    assertFalse(db.addCategory(username, "new 1"));
	    assertTrue(db.categoryExists(username, "new 1"));
	    
	    assertFalse(db.addCategory("does not exist", "new 3"));
	    assertFalse(db.userExists("does not exist"));
	    
	    assertTrue(db.addCategory(username, "A"));
	    assertTrue(db.categoryExists(username, "A"));
	    
	    try {
		db.addCategory(username, "");
		fail();
	    } catch (IllegalArgumentException IAE) {
		
	    }
	    
	    try {
		db.addCategory(username, null);
		fail();
	    } catch (IllegalArgumentException IAE) {
		
	    }
	    
	    try {
		db.addCategory(null, null);
		fail();
	    } catch (IllegalArgumentException IAE) {
		
	    }
	    
	    try {
		db.addCategory(null, "Home");
		fail();
	    } catch (IllegalArgumentException IAE) {
		
	    }
	    
	    try {
		db.addCategory(null, "new 2");
		fail();
	    } catch (IllegalArgumentException IAE) {
		
	    }
	    
	    db.close();
	}
	
//	public void testRemoveCategory()
//	{
//	    db.open();
//	    db.clear();
//	    
//	    String username = "username";
//	    db.createUser(username, "password", "name", "email");
//	    
//	    assertFalse(db.removeCategory(username, "does not exist"));
//	    assertFalse(db.categoryExists(username, "does not exist"));
//	    assertTrue(db.removeCategory(username, "Personal"));
//	    assertFalse(db.categoryExists(username, "Personal"));
//	    
//	    assertTrue(db.addCategory(username, "new category"));
//	    assertTrue(db.removeCategory(username, "new category"));
//	    assertFalse(db.categoryExists(username, "new category"));
//	    
//	    assertFalse(db.removeCategory("does not exist", "School"));
//	    assertFalse(db.userExists("does not exist"));
//	    
//	    assertFalse(db.removeCategory(username, ""));
//	    
//	    assertTrue(db.addCategory(username, "A"));
//	    assertTrue(db.removeCategory(username, "A"));
//	    
//	    try {
//		db.removeCategory(username, null);
//		fail();
//	    } catch (IllegalArgumentException IAE) {
//		
//	    }
//	    
//	    try {
//		db.removeCategory(null, null);
//		fail();
//	    } catch (IllegalArgumentException IAE) {
//		
//	    }
//	    
//	    try {
//		db.removeCategory("does not exist", null);
//		fail();
//	    } catch (IllegalArgumentException IAE) {
//		
//	    }
//	    
//	    try {
//		db.removeCategory(null, "Work");
//		fail();
//	    } catch (IllegalArgumentException IAE) {
//		
//	    }
//	    
//	    db.close();
//	}
	
	public void testIsValidEmailAddress() {
	    assertFalse(InputValidator.isValidEmailAddress(null));
	    assertFalse(InputValidator.isValidEmailAddress(""));
	    assertFalse(InputValidator.isValidEmailAddress(" "));
	    assertFalse(InputValidator.isValidEmailAddress("bob@"));
	    assertFalse(InputValidator.isValidEmailAddress("@.com"));
	    assertFalse(InputValidator.isValidEmailAddress("."));
	    assertFalse(InputValidator.isValidEmailAddress("@yahoo.com"));
	    assertFalse(InputValidator.isValidEmailAddress("lol@lol"));
	    assertFalse(InputValidator.isValidEmailAddress(" bob@bob.com"));
	    assertFalse(InputValidator.isValidEmailAddress("bob@bob.com "));
	    
	    assertTrue(InputValidator.isValidEmailAddress("a@b.com"));
	    assertTrue(InputValidator.isValidEmailAddress("bob@bob.com"));
	    assertTrue(InputValidator.isValidEmailAddress("professor@math.gatech.edu"));
	}
	
	public void testIsValidUsername() {
	    assertFalse(InputValidator.isValidUsername(null));
	    assertFalse(InputValidator.isValidUsername(""));
	    assertFalse(InputValidator.isValidUsername(" "));
	    assertFalse(InputValidator.isValidUsername(" hahaha"));
	    assertFalse(InputValidator.isValidUsername("foo "));
	    
	    assertTrue(InputValidator.isValidUsername("1"));
	    assertTrue(InputValidator.isValidUsername("username"));
	    assertTrue(InputValidator.isValidUsername("blink23232323;"));
	}

	
	public void testAddTask() {
		db.open();
		db.clear();
		assertFalse(db.addTask("username", new Task()));
		db.createUser("username", "password", "name", "email");
		Task t = new Task();
		t.setName("test1");
		assertTrue(db.addTask("username", t));
		db.clear();
		db.close();
	}
	
	public void testGetAllTasks() {
		db.open();
		db.clear();
		db.createUser("username", "password", "name", "email");
		Task[] expected = new Task[3];
		
		Task t = new Task();
		t.setName("test1");
		db.addTask("username", t);
		expected[0] = t;
		
		t = new Task();
		t.setName("test2");
		db.addTask("username", t);
		expected[1] = t;
		
		t = new Task();
		t.setName("test3");
		db.addTask("username", t);
		expected[2] = t;
		
		Task[] tArray = db.getAllTasks("username");
		
		for (int i = 0; i < tArray.length; i++) {
			assertEquals(expected[i].getName(), tArray[i].getName());
			assertEquals(expected[i].getDescription(), tArray[i].getDescription());
			assertEquals(expected[i].getId(), tArray[i].getId());
		}
		
		db.clear();
		db.close();
	}
	
	
	public void testIsValidLatitude() {
	    assertTrue(LocationHelper.isValidLatitude(90));
	    assertTrue(LocationHelper.isValidLatitude(-90));
	    assertTrue(LocationHelper.isValidLatitude(0));
	    assertTrue(LocationHelper.isValidLatitude(21));
	    assertFalse(LocationHelper.isValidLatitude(180));
	    assertFalse(LocationHelper.isValidLatitude(-180));
	    assertFalse(LocationHelper.isValidLatitude(-2000));
	}
	
	public void testIsValidLongitude() {
	    assertTrue(LocationHelper.isValidLongitude(180));
	    assertTrue(LocationHelper.isValidLongitude(-180));
	    assertTrue(LocationHelper.isValidLongitude(90));
	    assertTrue(LocationHelper.isValidLongitude(-90));
	    assertTrue(LocationHelper.isValidLongitude(25));
	    assertFalse(LocationHelper.isValidLongitude(2000));
	    assertFalse(LocationHelper.isValidLongitude(-2000));
	    assertFalse(LocationHelper.isValidLongitude(4343));
	}
	
	

	
	public void testIsValidRealName() {
		assertFalse(InputValidator.isValidRealName(null));
		assertFalse(InputValidator.isValidRealName(""));
		assertFalse(InputValidator.isValidRealName(" "));
		assertFalse(InputValidator.isValidRealName("rightspace "));
		assertFalse(InputValidator.isValidRealName(" leftspace"));
		assertFalse(InputValidator.isValidRealName("  spaces everywhere   "));
		
		assertTrue(InputValidator.isValidRealName("Real Name"));
		assertTrue(InputValidator.isValidRealName("another real name"));
	}
	
	public void testIsValidPassword() {
		assertFalse(InputValidator.isValidPassword(null));
		assertFalse(InputValidator.isValidPassword(""));
		
		assertTrue(InputValidator.isValidPassword("this should work"));
		assertTrue(InputValidator.isValidPassword(" soshouldthis!!!"));
		assertTrue(InputValidator.isValidPassword("_password_"));
		assertTrue(InputValidator.isValidPassword("foobar76"));
		assertTrue(InputValidator.isValidPassword("#$%#$%"));
	}
	


}
